/*
********************************************************************************
* Copyright (C) 2021, xiang.D <dx_65535@163.com>.
* All right reserved.
*
* File Name   : bridge_v2.cc
* Author      :
* Version     : V1.0
* Description :
* Journal     : 2021-10-30 version v2.0
* Brief       : Blog: https://blog.csdn.net/qq_38750572?spm=1001.2014.3001.5343
* Others      :
                Compile command: g++ -Wl,--no-as-needed -std=c++11 bridge.cc
********************************************************************************
*/
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class CApp
{
public:
    CApp()
    {

    }

    virtual ~CApp()
    {

    }
    virtual string GetName() = 0;
    virtual void ShowLogo() = 0;
    virtual void RunPlatform(string platform) = 0;
};

class CHonorOfKings : public CApp
{
public:
    CHonorOfKings(string logo)
    {
        mLogo = logo;
        mName = "HonorOfKings";
    }

    ~CHonorOfKings()
    {

    }

    string GetName()
    {
        return mName;
    }

    void ShowLogo()
    {
        cout << mLogo << " (" << mPlatform << ")" << endl;
    }

    void RunPlatform(string platform)
    {
        mPlatform = platform;
    }

private:
    string mName;
    string mLogo;
    string mPlatform;
};

class CWeChat : public CApp
{
public:
    CWeChat(string logo)
    {
        mLogo = logo;
        mName = "WeChat";
    }

    ~CWeChat()
    {

    }

    string GetName()
    {
        return mName;
    }

    void ShowLogo()
    {
        cout << mLogo << " (" << mPlatform << ")" << endl;
    }

    void RunPlatform(string platform)
    {
        mPlatform = platform;
    }

private:
    string mName;
    string mLogo;
    string mPlatform;
};

class CPhone
{
public:
    virtual ~CPhone()
    {

    }

    virtual void InstallApp(CApp *pApp) = 0;

    virtual void Uninstall(CApp *pApp) = 0;

    virtual void EnterApp(CApp *pApp) = 0;

    virtual void ShowAppList() = 0;
};

class CMate40: public CPhone
{
public:
    explicit CMate40(string name)
    {
        mName = name;
    }

    ~CMate40()
    {

    }

    void InstallApp(CApp *pApp)
    {
        pApp->RunPlatform(mName);
        mAppVec.push_back(pApp);
    }

    void Uninstall(CApp *pApp)
    {
        vector<CApp *>::iterator it;

        for (it = mAppVec.begin(); it != mAppVec.end(); ) {
            if ((*it)->GetName() == pApp->GetName()) {
                cout << "Uninstall " << (*it)->GetName() << " Success!" << endl;
                /* void removing the last element, coredump */
                it = mAppVec.erase(it);
            } else {
                it++;
            }
        }
    }

    void EnterApp(CApp *pApp)
    {
        pApp->ShowLogo();
    }

    void ShowAppList()
    {
        vector<CApp *>::iterator it;

        cout << "App List: ";
        for (it = mAppVec.begin(); it != mAppVec.end(); ) {
            cout << (*it)->GetName() << " ";
            it++;
        }
        cout << endl;
    }

private:
    string mName;
    vector <CApp*> mAppVec;
};

class CHonor30Pro : public CPhone
{
public:
    explicit CHonor30Pro(string name)
    {
        mName = name;
    }

    ~CHonor30Pro()
    {

    }

    void InstallApp(CApp *pApp)
    {
        pApp->RunPlatform(mName);
        mAppVec.push_back(pApp);
    }

    void Uninstall(CApp *pApp)
    {
        vector<CApp *>::iterator it;

        for (it = mAppVec.begin(); it != mAppVec.end(); ) {
            if ((*it)->GetName() == pApp->GetName()) {
                cout << "Uninstall " << (*it)->GetName() << " Success!" << endl;
                /* void removing the last element, coredump */
                it = mAppVec.erase(it);
            } else {
                it++;
            }
        }
    }

    void EnterApp(CApp *pApp)
    {
        pApp->ShowLogo();
    }

    void ShowAppList()
    {
        vector<CApp *>::iterator it;

        cout << "App List: ";
        for (it = mAppVec.begin(); it != mAppVec.end(); ) {
            cout << (*it)->GetName() << " ";
            it++;
        }
        cout << endl;
    }

private:
    string mName;
    vector <CApp*> mAppVec;
};

int main(int argc, char *argv[])
{
    CHonorOfKings theHonorOfKings("Timi");
    CWeChat theWeChat("Earth");

    // 定制 Honor 30 Pro 上的王者荣耀和微信
    CHonor30Pro thePhone("Honor 30 Pro");

    cout << "--- Honor 30 Pro ---" << endl;
    thePhone.InstallApp(&theHonorOfKings);
    thePhone.EnterApp(&theHonorOfKings);

    thePhone.InstallApp(&theWeChat);
    thePhone.EnterApp(&theWeChat);

    thePhone.ShowAppList();

    thePhone.Uninstall(&theWeChat);
    thePhone.ShowAppList();
    cout << endl;

    // 定制 Mate40 上的王者荣耀和微信
    CMate40 theMate40("Mate40");

    cout << "--- Mate40 ---" << endl;
    theMate40.InstallApp(&theHonorOfKings);
    theMate40.EnterApp(&theHonorOfKings);

    theMate40.InstallApp(&theWeChat);
    theMate40.EnterApp(&theWeChat);

    theMate40.ShowAppList();

    theMate40.Uninstall(&theWeChat);
    theMate40.ShowAppList();
    cout << endl;

    return 0;
}
